package com.heima.sjms.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 需求：在不修改list.add方法逻辑的基础上增强其功能，要求：每次添加完，自动打印添加的元素内容。
 * 使用动态代理实现!
 * 1. spring aop底层原理是什么？  -- 动态代理
 * 2. 动态代理的实现有哪些？      -- jdk实现和cjlib实现
 * 3. jdk和cjlib实现的区别？
 *      jdk基于proxy实现的动态代理，主要是基于接口来产生代理对象，
 *                              代理对象和原始对象实现了相同接口，是平级的兄弟关系
 *      cjlib基于enhacer实现的动态代理，主要是基于原始对象的类的字节码来产生代理对象，
 *                              代理对象可以理解为是原始对象的子类，是父子关系。
 */
public class Demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        List proxyList = (List) Proxy.newProxyInstance(list.getClass().getClassLoader(),
                list.getClass().getInterfaces(),
                new InvocationHandler() {
                    /*
                        Object proxy: 表示代理对象!
                        Method method: 表示本次被调用的方法对象!
                        Object[] args：表示本次调用方法传递的参数!
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if ("add".equals(method.getName())) {
                            System.out.println("本次添加的元素是："+args[0]);
                        }

                        //反射调用原始对象功能
                        Object ret = method.invoke(list, args);

//                        System.out.println("调用原始功能后的增强逻辑.....");
                        return ret;
                    }
                });
        proxyList.add("hello");
        proxyList.add("world");
        proxyList.add("java");

        System.out.println("list = " + list);
    }
}
